﻿using DGIS.Service.IService.IImageService;
using OSGeo.GDAL;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;

namespace DGIS.Service.Service.ImageService
{
    public class ImageCreateService : IImageCreateService
    {
        public bool CreateImgThumbnail(string imgPath, string thumbnailPath)
        {
            //注册支持格式
            OSGeo.GDAL.Gdal.AllRegister();
            //转换中文路径格式
            OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
            // 属性表字段支持中文 
            OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");

            Dataset ds = Gdal.Open(imgPath, Access.GA_ReadOnly);

            //设置缩略图的尺寸
            int width = ds.RasterXSize;
            int height = ds.RasterYSize;
            if (ds.RasterXSize > 800 || ds.RasterYSize > 800)
            {
                if (ds.RasterXSize > ds.RasterYSize)
                {
                    width = 800;
                    height = width * ds.RasterYSize / ds.RasterXSize;
                }
                else
                {
                    height = 800;
                    width = height * ds.RasterXSize / ds.RasterYSize;
                }
            }

            Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);

            //灰度图生成缩略图
            if (ds.RasterCount == 1)
            {
                double[] bytes = new double[width * height];
                Band band1 = ds.GetRasterBand(1);
                band1.ReadRaster(0, 0, band1.XSize, band1.YSize, bytes, width, height, 0, 0);
                //获取灰度图的最大最小值
                double[] maxandmin1 = { 0, 0 };
                band1.ComputeRasterMinMax(maxandmin1, 0);

                double noData = 0;
                int hasNoData;
                band1.GetNoDataValue(out noData, out hasNoData);

                //循环读取灰度值，并通过0-255颜色计算新颜色值，写入新图
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        double value = bytes[i + j * width];
                        if (noData == value || value <= -999)
                            value = maxandmin1[1];

                        int colorValue = 255;
                        if (maxandmin1[1] != maxandmin1[0])
                            colorValue = Convert.ToInt32((value - maxandmin1[0]) * 255 / (maxandmin1[1] - maxandmin1[0]));

                        if (colorValue < 0)
                            colorValue = 0;
                        if (colorValue > 255)
                            colorValue = 255;
                        System.Drawing.Color color = Color.FromArgb(colorValue, colorValue, colorValue);
                        bitmap.SetPixel(i, j, color);
                    }
                }

                band1.Dispose();
                band1 = null;

                bytes = null;
            }
            //RGB图生成缩略图
            else
            {
                //获取红色波段
                int[] r = new int[width * height];
                Band band1 = ds.GetRasterBand(1);
                band1.ReadRaster(0, 0, ds.RasterXSize, ds.RasterYSize, r, width, height, 0, 0);

                double[] maxandmin1 = { 0, 0 };
                band1.ComputeRasterMinMax(maxandmin1, 0);

                //获取绿色波段
                int[] g = new int[width * height];
                Band band2 = ds.GetRasterBand(2);
                band2.ReadRaster(0, 0, ds.RasterXSize, ds.RasterYSize, g, width, height, 0, 0);

                double[] maxandmin2 = { 0, 0 };
                band2.ComputeRasterMinMax(maxandmin2, 0);

                //获取蓝色波段
                int[] b = new int[width * height];
                Band band3 = ds.GetRasterBand(3);
                band3.ReadRaster(0, 0, ds.RasterXSize, ds.RasterYSize, b, width, height, 0, 0);

                double[] maxandmin3 = { 0, 0 };
                band3.ComputeRasterMinMax(maxandmin3, 0);

                //循环读取rgb颜色，并写入新图
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        int rVal = Convert.ToInt32(r[i + j * width]);
                        rVal = (int)((rVal - maxandmin1[0]) / (maxandmin1[1] - maxandmin1[0]) * 255);

                        int gVal = Convert.ToInt32(g[i + j * width]);
                        gVal = (int)((gVal - maxandmin2[0]) / (maxandmin2[1] - maxandmin2[0]) * 255);

                        int bVal = Convert.ToInt32(b[i + j * width]);
                        bVal = (int)((bVal - maxandmin3[0]) / (maxandmin3[1] - maxandmin3[0]) * 255);

                        if (rVal > 255)
                            rVal = 255;
                        if (rVal < 0)
                            rVal = 0;

                        if (gVal > 255)
                            gVal = 255;
                        if (gVal < 0)
                            gVal = 0;

                        if (bVal > 255)
                            bVal = 255;
                        if (bVal < 0)
                            bVal = 0;

                        Color color = Color.FromArgb(rVal, gVal, bVal);
                        bitmap.SetPixel(i, j, color);
                    }
                }
                //释放rgb数组
                r = null;
                g = null;
                b = null;

                band1.Dispose();
                band2.Dispose();
                band3.Dispose();

                band1 = null;
                band2 = null;
                band3 = null;
            }

            string savePath = string.Format("{0}Cache\\{1}.jpg", System.AppDomain.CurrentDomain.BaseDirectory, Guid.NewGuid().ToString());
            bitmap.Save(savePath, ImageFormat.Jpeg);

            //释放资源
            ds.Dispose();
            bitmap.Dispose();
            ds = null;
            bitmap = null;

            GC.Collect();

            return true;
        }
    }
}
